#include <stdio.h>
#include <jni.h>
#include <stdlib.h>

// C++层 native函数
jint getLengthOfStr(JNIEnv *env, jclass clazz, jstring str) {
    if (str == NULL) {
        // 抛出空指针异常
        jclass clz = env->FindClass("java/lang/NullPointerException");
        jmethodID methodId = env->GetMethodID(clz, "<init>", "()V");
        jthrowable throwable = (jthrowable) env->NewObject(clz, methodId);
        env->Throw(throwable);
        return 0;
    } else {
        jint len = env->GetStringUTFLength(str);
        if (len == 5) {
            // 抛出IllegalArgumentException异常
            env->ThrowNew(env->FindClass("java/lang/IllegalArgumentException"), "this is IllegalArgumentException error form C++, because the str length is 5");
            return 0;
        } else {
            return len;
        }

    }
}

/**
 * JNINativeMethod由三部分组成:
 * (1)Java中的函数名;
 * (2)函数签名,格式为(输入参数类型)返回值类型;
 *  (Ljava/lang/String;)I  I表示返回值为int型，(Ljava/lang/String;)表示需要一个String参数
 * (3)native函数名
 */
static JNINativeMethod gMethods[] = {
        {"getStrLength", "(Ljava/lang/String;)I", (void *) getLengthOfStr }
};

//System.loadLibrary过程中会自动调用JNI_OnLoad，在此进行动态注册
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
    JNIEnv *env = NULL;
    jint result = JNI_FALSE;

    //获取env指针
    if (jvm->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK) {
        return result;
    }
    if (env == NULL) {
        return result;
    }
    //获取类引用
    jclass clazz = env->FindClass("com/example/testndk/JNIDynamicUtils");
    if (clazz == NULL) {
        return result;
    }
    //注册方法
    if (env->RegisterNatives(clazz, gMethods, sizeof(gMethods) / sizeof(gMethods[0])) < 0) {
        return result;
    }
    //成功
    result = JNI_VERSION_1_6;
    return result;
}